import json
import uuid

import pandas as pd
import streamlit as st
import streamlit.components.v1 as components
from other.add_conditions_to_bpmn_flows import add_conditions_to_bpmn_flows
from other.update_parameter import sequence_json

# 数据库配置
database = {
    "dbname": "postgres",
    "user": "postgres",
    "password": "Rm15127373235*",
    "host": "39.107.64.125",
    "port": "5432"
}

def display(rows):
    # ===== 固定的流程顺序 =====
    stage_order = ["初审", "复审", "副终审", "终审"]

    # ===== 构造 {流程名 -> row} 映射 =====
    row_dict = {row[0]: row for row in rows}

    # ===== 按固定顺序筛选已有的流程 =====
    ordered_rows = [row_dict[stage] for stage in stage_order if stage in row_dict]

    # ===== 按顺序渲染 =====
    for i, row in enumerate(ordered_rows):
        print(row)
        bpmn_data = row[1]  #  BPMN XML 在第二列
        json_data_processed=row[2] #  处理掉控制节点的 JSON 数据在第三列
        json_data = row[3]  #  JSON 数据在第四列

        with st.expander(f"流程 {row[0]}", expanded=True):
            col1, col2 = st.columns([3, 2])  # 左：BPMN图，右：JSON数据

            # ==== 左侧：BPMN 渲染 ====
            with col1:
                try:
                    # 处理十六进制或二进制数据
                    if isinstance(bpmn_data, str) and bpmn_data.startswith('\\x'):
                        import binascii
                        bytes_bpmn = binascii.unhexlify(bpmn_data[2:])
                    elif isinstance(bpmn_data, (bytes, bytearray)):
                        bytes_bpmn = bpmn_data
                    else:
                        bytes_bpmn = bpmn_data.encode('utf-8')

                    xml_bpmn = bytes_bpmn.decode('utf-8').strip()

                    # ===== 1) XML → BPMN 对象 =====
                    import tempfile
                    from pm4py.objects.bpmn.importer import importer as bpmn_importer
                    with tempfile.NamedTemporaryFile(delete=False, suffix=".bpmn") as tmp:
                        tmp.write(xml_bpmn.encode("utf-8"))
                        tmp_path = tmp.name
                    bpmn_obj = bpmn_importer.apply(tmp_path)

                    #增加条件标签
                    hits = add_conditions_to_bpmn_flows(bpmn_obj, json.loads(json_data))

                    # ===== 2) Layout & 可视化 =====
                    from pm4py.visualization.bpmn import visualizer as bpmn_visualizer
                    from pm4py.objects.bpmn.layout import layouter
                    image_format = "svg"
                    layouted_bpmn = layouter.apply(bpmn_obj)
                    visualization = bpmn_visualizer.apply(
                        layouted_bpmn, parameters={"format": image_format}
                    )
                    vis_str = visualization.pipe(format="svg").decode("utf-8")
                    html_str = f"""
                    <div style="width:100%; text-align:center;">
                      <div style="display:inline-block; max-width:100%;">
                        {vis_str.replace("<svg ", '<svg style="max-width:100%; height:auto;" ')}
                      </div>
                    </div>
                    """

                    # ===== 3) 展示到 Streamlit =====
                    with st.expander("🖼️ 流程图", expanded=True):
                        st.components.v1.html(html_str, height=300, scrolling=True)
                        #st.image(vis_str, use_container_width=True)


                except Exception as e:
                    st.error(f"处理BPMN数据时出错: {str(e)}")
                    if 'xml_bpmn' in locals():
                        with st.expander("查看问题XML"):
                            st.code(xml_bpmn[:2000])

            # ==== 右侧：JSON 展示 ====
            with col2:
                sequence = json.loads(json_data_processed)
                print(sequence)
                normalized_data = []
                for item in sequence:
                    normalized_data.append({
                        "id": item.get("id", ""),
                        "now_state": item.get("now_state", ""),
                        "next_state": item.get("next_state", ""),
                        "condition": json.dumps(item.get("condition", ""), ensure_ascii=False) if isinstance(item.get("condition", ""), dict) else item.get("condition", ""),
                        "parameter": item.get("parameter", "")
                    })
                sequence_pd = pd.DataFrame(
                    normalized_data,
                    columns=["id", "now_state", "next_state", "condition", "parameter"]
                )
                st.dataframe(sequence_pd, use_container_width=True)

def display_for_api(rows):
    """
    为API接口提供流程数据，返回结构化的JSON数据
    基于display函数的逻辑，但返回JSON而不是HTML
    """
    # ===== 直接使用数据库中的顺序，不进行固定排序 =====
    # 按照数据库查询结果的顺序处理流程

    # ===== 处理每个流程 =====
    processed_flows = []
    
    for i, row in enumerate(rows):
        try:
            workflow_name = row[0]
            bpmn_data = row[1]  # BPMN XML 在第二列
            json_data_processed = row[2]  # 处理掉控制节点的 JSON 数据在第三列
            json_data = row[3]  # JSON 数据在第四列

            # ==== 处理BPMN数据生成SVG ====
            flowchart_svg = None

            try:
                # 处理十六进制或二进制数据
                if isinstance(bpmn_data, str) and bpmn_data.startswith('\\x'):
                    import binascii
                    bytes_bpmn = binascii.unhexlify(bpmn_data[2:])
                elif isinstance(bpmn_data, (bytes, bytearray)):
                    bytes_bpmn = bpmn_data
                else:
                    bytes_bpmn = bpmn_data.encode('utf-8')

                xml_bpmn = bytes_bpmn.decode('utf-8').strip()

                # ===== 1) XML → BPMN 对象 =====
                import tempfile
                from pm4py.objects.bpmn.importer import importer as bpmn_importer
                with tempfile.NamedTemporaryFile(delete=False, suffix=".bpmn") as tmp:
                    tmp.write(xml_bpmn.encode("utf-8"))
                    tmp_path = tmp.name
                bpmn_obj = bpmn_importer.apply(tmp_path)

                print("带条件的原始序列",json.loads(json_data))

                # 增加条件标签
                hits = add_conditions_to_bpmn_flows(bpmn_obj, json.loads(json_data))

                # ===== 2) Layout & 可视化 =====
                from pm4py.visualization.bpmn import visualizer as bpmn_visualizer
                from pm4py.objects.bpmn.layout import layouter
                image_format = "svg"
                layouted_bpmn = layouter.apply(bpmn_obj)
                visualization = bpmn_visualizer.apply(
                    layouted_bpmn, parameters={"format": image_format}
                )
                vis_str = visualization.pipe(format="svg").decode("utf-8")
                
                # 清理临时文件
                import os
                os.unlink(tmp_path)
                
                flowchart_svg = vis_str

            except Exception as e:
                print(f"处理BPMN数据时出错: {str(e)}")
                flowchart_svg = f"<svg><text>流程图生成失败: {str(e)}</text></svg>"

            # ==== 处理序列数据 ====
            sequence_data = []
            try:
                sequence = json.loads(json_data_processed)
                for item in sequence:
                    sequence_data.append({
                        "id": item.get("id", ""),
                        "now_state": item.get("now_state", ""),
                        "next_state": item.get("next_state", ""),
                        "condition": json.dumps(item.get("condition", ""), ensure_ascii=False) if isinstance(item.get("condition", ""), dict) else item.get("condition", ""),
                        "parameter": item.get("parameter", "")
                    })
            except Exception as e:
                print(f"处理序列数据时出错: {str(e)}")
                sequence_data = []

            # 添加到结果列表
            processed_flows.append({
                "workflow": workflow_name,
                "flowchart_svg": flowchart_svg,
                "sequence_data": sequence_data
            })

        except Exception as e:
            print(f"处理流程 {row[0]} 时出错: {str(e)}")
            # 即使出错也添加一个错误信息
            processed_flows.append({
                "workflow": row[0],
                "flowchart_svg": f"<svg><text>流程处理失败: {str(e)}</text></svg>",
                "sequence_data": []
            })

    return processed_flows